/*  
 *  Copyright 2006 Paul Jack.
 *
 *  This file is part of the Dex compiler suite. 
 *  
 *  Dex is free software; you can redistribute it and/or modify it
 *  under the terms of the GNU General Public License as published by the
 *  Free Software Foundation; either version 2 of the License, or (at your
 *  option) any later version.
 *  
 *  Dex is distributed in the hope that it will be useful, but
 *  WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
 *  Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
 */
package dex.compiler.model.definition;


import java.util.List;

import dex.compiler.model.base.ParseNode;


/**
 * A definition of a Dex construct.  Examples include global variables,
 * functions and classes.
 */
public abstract class Definition extends ParseNode {
	
	
	/**
	 * The access modifier for this definition.
	 */
	private Modifier modifier;
	
	
	/**
	 * The name of the thing being defined.
	 */
	private String name;
	
	
	/**
	 * The attributes associated with the thing being defined.
	 */
	private List<String> attributes;
	
	
	/**
	 * The comment associated with the thing being defined.
	 */
	private String comment;
	
	
	/**
	 * Constructs a new definition.
	 * 
	 * @param params  the parameters for construction
	 */
	public Definition(DefinitionParams params) {
		super(params.getPlace());
		if (params.getModifier() == null) {
			throw new IllegalArgumentException("Modifier may not be null.");
		}
		if (params.getName() == null) {
			throw new IllegalArgumentException("Name may not be null.");
		}
		if (params.getAttributes() == null) {
			throw new IllegalArgumentException("Attributes list may not be null.");
		}
		if (params.getComment() == null) {
			params.setComment("");
		}
		this.modifier = params.getModifier();
		this.name = params.getName();
		this.attributes = params.getAttributes();
		this.comment = params.getComment();
	}

	
	/**
	 * Returns the access modifier for this definition.  
	 * 
	 * @return  the access modifier for this definition
	 */
	public Modifier getModifier() {
		return modifier;
	}


	/**
	 * Returns the attributes for this definition.  The attributes are
	 * simple tags that can be associated with a Dex construct.  Macros
	 * can examine the attributes and take appropriate action.
	 * 
	 * @return  the attributes.
	 */
	public List<String> getAttributes() {
		return attributes;
	}


	/**
	 * Returns the comment immediately preceding this definition, if any.
	 * Similar to javadoc, Dex treats these comments as part of the definition
	 * of the construct.  Usually comments are added to the parse tree as they 
	 * occur, but it's often useful for a macro to examine the comments 
	 * associated with a definition directly.
	 * 
	 * <p>Note this method never returns null; if no comment is associated with
	 * the definition, then the empty string is returned.
	 * 
	 * @return  the comment
	 */
	public String getComment() {
		return comment;
	}


	/**
	 * Returns the name of the thing being defined.
	 * This must be a valid Dex identifier.
	 * 
	 * @return  the name of thing being defined
	 */
	public String getName() {
		return name;
	}


	/**
	 * Prints the comment, attributes and modifier to the given
	 * buffer as Dex.
	 * 
	 * @param buffer  the buffer to print the Dex code to
	 */
	void print(StringBuilder buffer) {
		buffer.append("/*").append(comment).append("*/");
		for (String s : attributes) {
			buffer.append(' ').append('@').append(s);
		}
		buffer.append(' ').append(modifier.getCode()).append(' ');
	}


}
